package swym.client;

import java.util.*;
import java.net.*;
import java.io.*;
import swym.protocol.*;
import swym.server.*;
import swym.server.file.*;

public class SwymClient implements Runnable, WatchListener
{
    private Socket socket;
    private ObjectInputStream kpAlvIn;
    private ObjectOutputStream kpAlvOut;
    private Watch watcher;
    private String serverIP,userName, clientName,watchDir;
    private int port;
    private boolean registered;
    
    public SwymClient()
    {
        getLoginInformation();
        
        watcher = new Watch(new File(watchDir),clientName);
        watcher.addWatchListener(this);
                             
        try
        {
            socket = new Socket(serverIP,port);
            kpAlvOut = new ObjectOutputStream(socket.getOutputStream()); 
            kpAlvIn = new ObjectInputStream(socket.getInputStream());
            System.out.println("Connected to Server " + serverIP + ":" + port);
            
            serverLogin();
            (new Thread(this)).start(); //start listening for broadcast messages
            (new FileChunkSender( serverIP, port, new User(userName), new Client(clientName) )).start(); 
        }
        catch(UnknownHostException uhe)
        {
            System.out.println("Could not find server at " + serverIP);
            //System.exit(1);
        }
        catch(Exception e)
        {
            System.out.println("Error occured while connecting to server.");
            //System.exit(1);
        }
        
    }
    
    private void getLoginInformation()
    {
        File configFile = new File( System.getProperty("user.dir") + File.separator + "config.txt" );
        registered = configFile.exists();
        
        if(registered)
        {            
            Settings.loadSettings( configFile );
            serverIP = Settings.getProperty("serverIP");
            port = Integer.parseInt(Settings.getProperty("port"));
            userName = Settings.getProperty("userName");
            clientName = Settings.getProperty("clientName");
            watchDir = Settings.getProperty("watchDir");
        }
        else
        {
            BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
            try
            {
                System.out.print("Server IP: ");
                serverIP = stdIn.readLine();
                Settings.setProperty("serverIP", serverIP);
                System.out.print("Port: ");
                port = Integer.parseInt(stdIn.readLine());            
                Settings.setProperty("port", port + "");
                System.out.print("User name: ");
                userName = stdIn.readLine();
                Settings.setProperty("userName", userName);
                System.out.print("Client name: ");
                clientName = stdIn.readLine();
                Settings.setProperty("clientName", clientName);
                System.out.print("Watch Directory: ");
                watchDir = stdIn.readLine();
                Settings.setProperty("watchDir", watchDir);
            
                Settings.writeSettings( configFile );
            }
            catch(IOException ioe){ioe.printStackTrace();}
            
            
        }
   }
    
    private void serverLogin()
    {
        ConfirmActionMessage confirmMsg;
        
        try
        {
            if(registered)
            {
                LoginActionMessage msg = new LoginActionMessage(userName,clientName,0);
                msg.indicateUpdateConnection(true);
                kpAlvOut.writeObject( msg );
                kpAlvOut.flush();
            }
            else
            {
                RegisterActionMessage msg = new RegisterActionMessage(userName,clientName,0);
                msg.indicateUpdateConnection(true);
                kpAlvOut.writeObject( msg );
                kpAlvOut.flush();
            }
            confirmMsg = (ConfirmActionMessage)kpAlvIn.readObject();
            if ( confirmMsg.getReturnCode() != 0 )
            {
                   System.out.println("Failed to login or register with server");
                    System.exit(1);
            }
            else
                System.out.println("Login successful");
        }
        catch(IOException ioe)
        {
            ioe.printStackTrace();
        }
        catch(ClassNotFoundException cnfe)
        {
            cnfe.printStackTrace();
        }
    }
    
    public void run()
    {
        ActionMessage msg;       
        try
        {
             while((msg = (ActionMessage)kpAlvIn.readObject()) != null)
            {
                
            }
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
        catch(ClassNotFoundException e){e.printStackTrace();}
    }    
     
    public void fileRemoved(File file)
    {
        
    }
    
    public void fileAdded(File file)
    {
        String version = "1";  //getversionfrom versionFile stored client directory
        String folderPath = file.getAbsolutePath().replace(watcher.getWatchDirectory().getAbsolutePath(),"");
        folderPath = folderPath + "." + version;
        
        (new FileChunkWriter(file, folderPath)).start();       
    }    

    public static void main(String [] args)
    {
        new SwymClient();
    }
}

